﻿using FileSynchronizationClient.Common;
using FileSynchronizationClient.Models;

namespace FileSynchronizationClient.Service
{
    public class PublishService
    {
        private SettingMap _settingMap;

        private SyncPackHttpClient _client;

        private long chunkSize = 2097152;

        public PublishService(
            SyncPackHttpClient syncPackHttpClient,
            SettingMap settingMap)
        {
            _client = syncPackHttpClient;
            _settingMap = settingMap;
        }

        public async Task PublishAsync()
        {
            Console.WriteLine("开始打包....");

            #region 项目打包
            //打包
            await CommonHelper.RunCmd(_settingMap.BuildCMD);
            #endregion

            #region 获取文件
#if DEBUG
            var basePath = @"D:\work\Wechat_PublicNumber\bin\Release\net6.0\publish";
#else
            var basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, _settingMap.DistPath);
#endif

            // 获取源文件夹中的所有文件和文件夹
            string[] files = Directory.GetFiles(basePath, "*", SearchOption.AllDirectories);

            //后端特殊处理 只要这几个后缀结尾的文件
            if (_settingMap.Type == (int)PublishType.WeChatService)
                files = files.Where(f => f.EndsWith(".exe") || f.EndsWith(".xml")).ToArray();
            #endregion

            #region 同步过程
            var allFileChunk = 0;

            #region 删除远程包，并检索本地文件获取需要上传总片数
            //等待画面
            CommonHelper.CircleLoading("正在检索需要同步的文件.... ", async () =>
            {
                //先清空远程pack
                var clearRetrun = await _client.ClearPackFile(_settingMap.Type);
                if (clearRetrun.Code != 200) throw new Exception($"删除远程包失败，错误：{clearRetrun.Error}");

                //获取总片数
                foreach (var item in files)
                {
                    using (var fileStream = File.OpenRead(item))
                    {
                        allFileChunk += (int)Math.Ceiling(fileStream.Length * 1.00 / chunkSize);
                    }
                }
            });
            Console.WriteLine();
            #endregion

            #region 上传文件

            Thread.Sleep(100);

            CommonHelper.Progress("正在上传文件", allFileChunk, async (progress) =>
                {
                    //百分比加载
                    for (int i = 0; i <= files.Length; i++)
                    {
                        if (i != 0)
                        {
                            var file = files[i - 1];

                            using (FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read))
                            {
                                byte[] buffer = new byte[chunkSize];
                                int bytesRead;
                                int chunkIndex = 0;
                                string guid = Guid.NewGuid().ToString();
                                var totalChunks = Math.Ceiling(fileStream.Length * 1.00 / chunkSize);
                                var fileName = Path.GetFileName(file);
                                string relativePath = Path.GetRelativePath(basePath, file);
                                var dirPath = relativePath.Substring(0, relativePath.IndexOf(Path.GetFileName(relativePath)));

                                //分片
                                if (fileStream.Length > chunkSize)
                                {
                                    while ((bytesRead = await fileStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
                                    {
                                        byte[] chunkData = new byte[bytesRead];
                                        Array.Copy(buffer, chunkData, bytesRead);

                                        await _client.UploadFile(_settingMap.Type, chunkData, fileName, dirPath, chunkIndex + 1, (int)totalChunks, guid);

                                        chunkIndex++;
                                        progress.currentProgress++;
                                    }
                                }
                                //不分片
                                else
                                {
                                    byte[] chunkData = new byte[fileStream.Length];
                                    await fileStream.ReadAsync(chunkData, 0, chunkData.Length);
                                    await _client.UploadFile(_settingMap.Type, chunkData, fileName, dirPath);
                                    progress.currentProgress++;
                                }
                            }
                        }
                    }
                });
            Console.WriteLine();
            Console.WriteLine();
            #endregion

            #region 开启同步
            //等待画面
            CommonHelper.CircleLoading("正在同步文件.... ", async () =>
            {
                var syncRetrun = await _client.SyncPackFile(_settingMap.Type);
                if (syncRetrun.Code != 200) Console.WriteLine($"同步失败，错误：{syncRetrun.Error}");
            });
            Console.WriteLine();
            #endregion

            #region 删除包备份
            //删除包备份
            await _client.RemovePackBak(_settingMap.Type);
            #endregion 
            #endregion

            Console.WriteLine($"同步完成！！");
        }
    }
}
